package StudyCode.summary.zipfile;

import java.io.IOException;
import java.net.URI;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;

/**
 * 版权所有 科技与人文(www.tah1986.com)
 */
public class UnzipsFileToGivenDirectory {
	public static void unzip(String zipFilename, String destDirname)
			throws IOException {
		unzip1(zipFilename, destDirname);
	}

	public static void unzip1(String zipFilename, String destDirname)
			throws IOException {

		final Path destDir = Paths.get(destDirname);
		if (Files.notExists(destDir)) {
			Files.createDirectories(destDir);
		}

		try (FileSystem zipFileSystem = createZipFileSystem(zipFilename,
				false)) {
			final Path root = zipFileSystem.getPath("/");

			Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
				@Override
				public FileVisitResult visitFile(Path file,
				                                 BasicFileAttributes attrs) throws IOException {

					final Path destFile = Paths.get(destDir.toString(),
							file.toString());

					Files.copy(file, destFile,
							StandardCopyOption.REPLACE_EXISTING);
					return FileVisitResult.CONTINUE;
				}

				@Override
				public FileVisitResult preVisitDirectory(Path dir,
				                                         BasicFileAttributes attrs) throws IOException {
					final Path dirToCreate = Paths.get(destDir.toString(),
							dir.toString());
					if (Files.notExists(dirToCreate)) {

						Files.createDirectory(dirToCreate);
					}
					return FileVisitResult.CONTINUE;
				}
			});
		}
	}

	private static FileSystem createZipFileSystem(String zipFilename, boolean create) throws IOException {
		final Path path = Paths.get(zipFilename);
		final URI uri = URI.create("jar:file:" + path.toUri().getPath());

		final Map<String, String> env = new HashMap<>();
		if (create) {
			env.put("create", "true");
		}
		return FileSystems.newFileSystem(uri, env);
	}
}
